/*
 * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS HEADER.
 *
 * Copyright 2010 huliqing, huliqing.cn@gmail.com
 *
 * This file is part of QFaces.
 * QFaces is free software: you can redistribute it and/or modify
 * it under the terms of the GNU Lesser General Public License as published by
 * the Free Software Foundation, either version 3 of the License, or
 * (at your option) any later version.
 *
 * QFaces is distributed in the hope that it will be useful,
 * but WITHOUT ANY WARRANTY; without even the implied warranty of
 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
 * GNU Lesser General Public License for more details.
 *
 * You should have received a copy of the GNU Lesser General Public License
 * along with QFaces.  If not, see <http://www.gnu.org/licenses/>.
 *
 * 这个文件是QFaces的一部分。
 * 您可以单独使用或分发这个文件，但请不要移除这个头部声明信息.
 * QFaces是一个自由软件，您可以自由分发、修改其中的源代码或者重新发布它，
 * 新的任何修改后的重新发布版必须同样在遵守LGPL3或更后续的版本协议下发布.
 * 关于LGPL协议的细则请参考COPYING、COPYING.LESSER文件，
 * 您可以在QFaces的相关目录中获得LGPL协议的副本，
 * 如果没有找到，请连接到 http://www.gnu.org/licenses/ 查看并获取副本。
 *
 * - Author: Huliqing
 * - Contact: huliqing.cn@gmail.com
 * - License: GNU Lesser General Public License (LGPL)
 * - Blog and source code availability: http://www.huliqing.name/
 */

package name.huliqing.qfaces.render;

import java.io.IOException;
import java.util.Map;
import java.util.logging.Logger;

import javax.el.MethodExpression;
import javax.faces.component.UIComponent;
import javax.faces.context.FacesContext;
import javax.faces.context.ResponseWriter;
import javax.faces.render.Renderer;

import name.huliqing.qfaces.QFaces;
import name.huliqing.qfaces.component.Ajax;
import name.huliqing.qfaces.component.Frame;
import name.huliqing.qfaces.component.Helper;
import name.huliqing.qfaces.component.Frame.CssPosition;

public class HelperRenderer extends Renderer implements Ajax {

    private final static Logger logger = Logger.getLogger(HelperRenderer.class.getName());
    // 整个组件的ID
    private String ID_CLIENT;
    // “打开”按钮的ID
    private String ID_BUTTON;
    // "内容"区域的id(只包含内容)
    private String ID_CONTENT;

    @Override
    public void encodeBegin(FacesContext fc, UIComponent ui)
            throws IOException {
        super.encodeBegin(fc, ui);
        Helper h = (Helper) ui;
        QFaces.getResLoader2().loadJavaScript(h, "Helper.js");

        if (h.getLazy() == null) {
            h.setLazy(Boolean.TRUE);
        }

        if (h.getImage() == null) {
            h.setImage(QFaces.getResLoader2().makeImageSrc("10.png"));
        }

        if (h.getTip() == null) {
            h.setTip("Click me");
        }

        if (h.getMessage() == null) {
            h.setMessage("");
        }

        if (h.getStyle() == null) {
            h.setStyle("");
        }

        if (h.getStyleClass() == null) {
            h.setStyleClass("");
        }

        if (h.getFrame() == null) {
            h.setFrame(new Frame());
            h.getFrame().loadAttributeFrom(h);
            if (h.getFrame().getCssPosition() == null) {
                h.getFrame().setCssPosition(CssPosition.ABSOLUTE.name());
            }
        }

        if (h.getHelpId() == null) {
            h.setHelpId("");
        }

        this.ID_CLIENT = h.getClientId(fc);
        this.ID_BUTTON = this.ID_CLIENT + ":button";
        this.ID_CONTENT = this.ID_CLIENT + ":content";

        // ---- 渲染组件
        ResponseWriter rw = fc.getResponseWriter();
        rw.startElement("span", h);
        rw.writeAttribute("id", this.ID_CLIENT, null);
        rw.writeAttribute("style", "border:0;", null);
        rw.startElement("img", h);
        rw.writeAttribute("id", ID_BUTTON, null);
        rw.writeAttribute("name", ID_BUTTON, null);
        rw.writeAttribute("style", "vertical-align:middle;", null);
        rw.writeAttribute("src", h.getImage(), null);
        rw.writeAttribute("title", h.getTip(), null);
        rw.endElement("img");
        renderBody(fc, h);
        rw.endElement("span");

        // ---- 初始化
        StringBuilder sb = new StringBuilder("Q.F.UIHelper.init(")
                .append(" \"" + this.ID_CLIENT + "\"")
                .append(",\"" + this.getClass().getName() + "\"")
                .append(",\"" + (h.getListener() != null ? h.getListener().getExpressionString() : "") + "\"")
                .append(",\"" + h.getLazy() + "\"")
                .append(",\"" + this.ID_BUTTON + "\"")
                .append(",\"" + h.getFrame().getFrameId() + "\"")
                .append(",\"" + this.ID_CONTENT + "\"")
                .append(",\"" + h.getHelpId() + "\"")
                .append(");");

        QFaces.getResLoader2().loadJavaScriptInit(h, sb.toString());
    }

    @Override
    public void encodeEnd(FacesContext fc, UIComponent ui)
            throws IOException {
        super.encodeEnd(fc, ui);
    }

    public void renderBody(FacesContext fc, Helper h) throws IOException {
        h.getFrame().encodeBegin(fc);

        ResponseWriter rw = fc.getResponseWriter();
        // 如果直接绑定了message,则不进行listener绑定
        String helpMessage = "";
        if (h.getMessage() != null) {
            helpMessage = h.getMessage();
        } else {
            if (h.getListener() == null) {
                logger.warning("You must binding at least one attribute \"message\" or \"listener\" ");
            } else {
                String args = h.getHelpId();
                if (!h.getLazy()) {
                    logger.fine("\"message\" not found, now fecth data from \"listener\"");
                    helpMessage = (String) h.getListener().invoke(fc.getELContext(), new Object[]{args});
                }
            }
        }
        rw.startElement("table", h);
        rw.writeAttribute("border", "0", null);
        rw.writeAttribute("cellspacing", "0", null);
        rw.writeAttribute("cellpadding", "0", null);
        rw.writeAttribute("class", h.getStyleClass(), null);
        rw.writeAttribute("style", h.getStyle(), null);
        if (h.getWidth() != null) {
            rw.writeAttribute("width", h.getWidth(), null);
        }
        rw.startElement("tr", h);
            rw.startElement("td", h);
            rw.writeAttribute("id", ID_CONTENT, null);
                rw.writeText(helpMessage, null);
            rw.endElement("td"); 
        rw.endElement("tr");
        rw.endElement("table");

        // remove
//        rw.startElement("div", h);
//        rw.writeAttribute("id", ID_CONTENT, null);
//        rw.writeAttribute("name", ID_CONTENT, null);
//        rw.writeAttribute("class", h.getStyleClass(), null);
//        rw.writeAttribute("style", h.getStyle(), null);
//        rw.writeText(helpMessage, null);
//        rw.endElement("div");

        // End frame render.
        h.getFrame().encodeEnd(fc);
    }

    public void ajax(Map<String, String> params, FacesContext fc) {
        String listenerExp = params.get("listenerExp");
        String helpId = params.get("helpId");
        MethodExpression listener = QFaces.createMethodExpression(listenerExp, String.class, new Class[]{String.class});

        String helpMessage = (String) listener.invoke(fc.getELContext(), new Object[]{helpId});
        QFaces.getResponse().responseHTML(fc, helpMessage);
    }
}
